<template>
  <el-dialog
    title="内容编辑"
    v-model="visible"
    top="10vh"
    width="80%"
    :before-close="handleClose"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
  >
    <el-row :gutter="20">
      <el-col :span="16">
        <el-form
          ref="dataFormRef"
          :model="dataForm"
          :rules="dataFormRules"
          label-position="right"
          label-width="120px"
          v-loading="loading"
        >
          <el-tabs
            v-model="activeNames"
            class="tabs"
          >
            <el-tab-pane label="内容配置" name="1">
              <el-form-item label="内容标题" prop="title">
                <el-input v-model="dataForm.title" placeholder="请输入内容标题"></el-input>
                <el-button @click="aiEvent('xuxie', 'title', '标题')">AI续写</el-button>
                <el-button @click="aiEvent('fanyi', 'title', '标题')">AI英语翻译</el-button>
              </el-form-item>
              <el-form-item label="内容简介" prop="intro">
                <el-input type="textarea" v-model="dataForm.intro" placeholder="请输入内容简介"></el-input>
                <el-button @click="aiEvent('xuxie', 'intro', '简介')">AI续写</el-button>
                <el-button @click="aiEvent('fanyi', 'intro', '简介')">AI英语翻译</el-button>
              </el-form-item>
              <el-form-item label="内容栏目" prop="columnId">
                <el-select v-model="dataForm.columnId" class="m-2" placeholder="请选择栏目" size="large">
                  <el-option v-for="item in columnAllList" :key="item.id" :label="item.title" :value="item.id"></el-option>
                </el-select>
              </el-form-item>
              <el-form-item label="内容标签" prop="tagsList">
                <el-checkbox-group v-model="tagsList">
                  <el-checkbox v-for="item in tagsAllList" :key="item.id" :label="item.id">
                    {{ item.title }}
                  </el-checkbox>
                </el-checkbox-group>
              </el-form-item>
              <el-form-item label="内容推荐" prop="recomList">
                <el-checkbox-group v-model="recomList">
                  <el-checkbox label="recom">推荐</el-checkbox>
                  <el-checkbox label="frontPage">头条</el-checkbox>
                </el-checkbox-group>
              </el-form-item>
              <el-form-item label="内容发布时间" prop="publishDate">
                <el-date-picker
                  v-model="dataForm.publishDate"
                  type="datetime"
                  placeholder="请选择发布时间"
                />
              </el-form-item>
              <el-form-item label="内容排序" prop="orderNum">
                <el-input-number
                  v-model.number="dataForm.orderNum"
                  :step="1"
                  :precision="0"
                  step-strictly
                ></el-input-number>
              </el-form-item>
              <el-form-item label="内容seo关键词" prop="keyword">
                <el-input v-model="dataForm.keyword" placeholder="请输入内容seo关键词"></el-input>
              </el-form-item>
              <el-form-item label="内容seo描述" prop="description">
                <el-input v-model="dataForm.description" placeholder="请输入内容seo描述"></el-input>
              </el-form-item>
            </el-tab-pane>
            <el-tab-pane label="内容详情" name="2">
              <el-form-item label="内容价格" prop="price">
                <el-input-number
                  v-model.number="dataForm.price"
                  :min="0"
                  :step="0.01"
                  :precision="2"
                  step-strictly
                ></el-input-number>
              </el-form-item>
              <el-form-item label="内容原价" prop="originalPrice">
                <el-input-number
                  v-model.number="dataForm.originalPrice"
                  :min="0"
                  :step="0.01"
                  :precision="2"
                  step-strictly
                ></el-input-number>
              </el-form-item>
              <el-form-item label="内容图片组合" prop="img">
                <div class="uploadBox">
                  <el-upload
                    v-model:file-list="fileList"
                    class="img-uploader"
                    action="#"
                    :auto-upload="false"
                    list-type="picture-card"
                    :on-change="uploadCodeClickEvent"
                    :on-preview="handlePictureCardPreview"
                    :on-remove="handlePictureCardDelete"
                  >
                    <el-icon class="img-uploader-icon"><Plus /></el-icon>
                  </el-upload>
                </div>
                <el-button type="primary" @click="clickOssEvent">从素材库选择</el-button>
              </el-form-item>
              <el-alert title="默认第一张为内容封面图" type="warning" :closable="false" />
              <el-form-item label="内容详情" prop="content">
                <div ref="richTextRef" style="height: 600px"></div>
              </el-form-item>
            </el-tab-pane>
          </el-tabs>
        </el-form>
            </el-col>
      <el-col :span="8">
        <div class="dialogue">
          <div class="title">大山AI对话框</div>
          <div class="dialogueBox">
            <div class="dialogueItems">
              <div class="dialogueItem" v-for="(item, index) in aiList" :key="index">
                <SvgIcon name="ai" />
                <div class="content">
                  {{ item.content }}
                </div>
              </div>
            </div>
            <div class="aiDialog">
              <div class="btnBox">
                <el-button round size="small" @click="clearDialog">清空对话框</el-button>
                <el-button round type="primary" size="small" v-for="item in aiBtnList" :key="item.keys" @click="insertionContent(item.keys)">赋予{{ item.label }}</el-button>
              </div>
              <el-alert title="赋予AI内容的时候是最新的一条，如需其它内容，请手动复制" type="warning" :closable="false" />
              <div class="content">
                <el-input type="textarea" v-model="aiContent" placeholder="请输入内容"></el-input>
                <div class="submintBtn">
                  <el-button type="primary" :loading="aiBtnLoading" round @click="submitAiDialog">
                    <el-icon><Position /></el-icon>
                    {{ !aiBtnLoading ? '发送' : 'AI生成中' }}
                  </el-button>
                </div>
              </div>
            </div>
          </div>
        </div>
      </el-col>
    </el-row>
    <template #footer>
      <el-button @click="handleClose">取消</el-button>
      <el-button type="primary" @click="updateOrCreate">确定</el-button>
    </template>

    <el-dialog v-model="dialogVisible">
      <img w-full :src="dialogImageUrl" alt="Preview Image" />
    </el-dialog>

    <!-- 素材库 -->
    <OssWarehouse v-model="showOss" @change="enterOss"></OssWarehouse>
  </el-dialog>
</template>

<script lang="ts" setup>

import { AiEditor } from "aieditor";
import "aieditor/dist/style.css"
import { Plus, Position } from '@element-plus/icons-vue'

import { ref, watch, onMounted, onUnmounted, type PropType } from 'vue'
import { UPDATE_MODEL_EVENT } from 'cm/contants'
import { updateContent, getContentInfo, type ContentApiResult, type ICreateOrUpdateContent } from '@/api/content'
import { ElMessage } from 'element-plus'
import { getToken } from '@/utils/cache'
import { fileUpload, type OssApiResult, type uploadFile } from '@/api/oss'
import appConfig from '@/config/index'

import OssWarehouse from '@/components/oss/index.vue'

import {
  getTagsAllList,
  type TagsApiResult
} from '@/api/tags'

import { aiSocket, aiDialogSocket } from '@/utils/socket'

import { type ColumnApiResult } from '@/api/column'

const props = defineProps({
  modelValue: {
    type: Boolean,
    required: true,
    default: false
  },
  currId: {
    type: String,
    required: true,
    default: ''
  },
  columnAllList: {
    type: Array as PropType<ContentApiResult[]>,
    default: () => []
  }
})

const emit = defineEmits([UPDATE_MODEL_EVENT, 'change'])

const visible = ref<boolean>(false)

const defaultForm = {
  id: '',
  title: '',
  intro: '',
  columnId: '0',
  tags: [],
  recom: '',
  publishDate: '',
  price: 0.00,
  originalPrice: 0.00,
  img: '',
  keyword: '',
  description: '',
  content: '',
  orderNum: 0
}
// 表单逻辑
const dataForm = ref<ICreateOrUpdateContent>({ ...defaultForm })

const dataFormRules = {
  title: [{ required: true, message: '请输入标题', trigger: 'blur' }],
  orderNum: [{ required: true, message: '请输入排序', trigger: 'blur' }],
  keyword: [{ required: true, message: '请输入关键词', trigger: 'blur' }],
  description: [{ required: true, message: '请输入描述', trigger: 'blur' }],
}

const richTextRef = ref();
let aiEditor: AiEditor;

const tagsAllList = ref<TagsApiResult[]>([])

const getTagsListApi = async () => {
  loading.value = true
  const res = await getTagsAllList()
  loading.value = false
  if (res?.code === 200) {
    tagsAllList.value = res.data as TagsApiResult[]
  } else {
    ElMessage({ message: res?.msg || '网络异常，请稍后重试', type: 'error' })
  }
}

const activeNames = ref<string>('1');

const fileList = ref<Array<object>>([])
const submotFileList = ref<Array<any>>([])
const recomList = ref<Array<string>>([])
const tagsList = ref<Array<string>>([])

const loading = ref<boolean>(false)
// 查询内容详情
const getContentInfoApi = async (currId: string) => {
  loading.value = true
  const res = await getContentInfo(currId)
  loading.value = false
  if (res?.code === 200) {
    dataForm.value = res.data as ICreateOrUpdateContent;
    if (dataForm.value.img !== '') {
      let imgs = dataForm.value.img as string
      let imgArray: Array<string> = (<string>imgs).split(',')
      const imgArrays: Array<object> = imgArray.map((item, index) => {
        const obj = {
          uid: index,
          url: `${appConfig.api.staticUrl}${item}`,
          name: item
        }
        return obj
      })
      fileList.value = imgArrays;
      submotFileList.value = imgArrays;
    }
    const recom = dataForm.value.recom as string
    recomList.value = recom.split(',')
    tagsList.value = dataForm.value.tags as Array<string>
    const content: string = dataForm.value.content as string
    aiEditor.focus().insert(content);
  }
}

watch(
  () => props.modelValue,
  async () => {
    visible.value = props.modelValue
    if (props.modelValue && props.currId) {
      setTimeout(async() => {
        aiEditor = await new AiEditor({
          element: richTextRef.value as Element,
          placeholder: "点击输入内容...",
          theme: "light",
          content: '',
          contentRetention: false, // 是否自动保存（缓存）当前编辑的内容
          image: {
            allowBase64: false,
            uploadHeaders: {
              "Authorization": getToken(),
            },
            uploader: (file: File, uploadUrl: string, headers: Record<string, any>, formName: string): 
              Promise<Record<string, any>> => {
                console.log(file, uploadUrl, headers, formName)
                return new Promise(async (resolve, reject) => {
                  //可自定义图片上传逻辑
                  const formData = new FormData()
                  formData.append('file', file)
                  formData.append('business', '内容管理-内容详情-图片')
                  formData.append('type', 'text')
                  const res = await fileUpload(formData)
                  console.log(res?.code)
                  if (res?.code === 200) {
                    ElMessage({ type: 'success', message: '上传成功' });
                    const data = res.data as OssApiResult[];
                    aiEditor.focus().insert(`<p><img src="${data[0].url}" /></p>`)
                    resolve(res);
                    
                  } else {
                    reject(res)
                    ElMessage({ type: 'error', message: res?.msg || '网络异常，请稍后重试' })
                  }
                });
            },
          },
          ai: {
            models: {
              xinghuo: {
                appId: "",
                apiKey: "",
                apiSecret: "",
              }
            },
            menus:[
              {
                icon: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"></path><path d="M4 18.9997H20V13.9997H22V19.9997C22 20.552 21.5523 20.9997 21 20.9997H3C2.44772 20.9997 2 20.552 2 19.9997V13.9997H4V18.9997ZM16.1716 6.9997L12.2218 3.04996L13.636 1.63574L20 7.9997L13.636 14.3637L12.2218 12.9495L16.1716 8.9997H5V6.9997H16.1716Z"></path></svg>`,
                name: "AI 续写",
                prompt: "请帮我继续扩展一些这段话的内容",
                text: "focusBefore",
                model: "xinghuo"
              },
              {
                icon: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"></path><path d="M15 5.25C16.7949 5.25 18.25 3.79493 18.25 2H19.75C19.75 3.79493 21.2051 5.25 23 5.25V6.75C21.2051 6.75 19.75 8.20507 19.75 10H18.25C18.25 8.20507 16.7949 6.75 15 6.75V5.25ZM4 7C4 5.89543 4.89543 5 6 5H13V3H6C3.79086 3 2 4.79086 2 7V17C2 19.2091 3.79086 21 6 21H18C20.2091 21 22 19.2091 22 17V12H20V17C20 18.1046 19.1046 19 18 19H6C4.89543 19 4 18.1046 4 17V7Z"></path></svg>`,
                name: "AI 优化",
                prompt: "请帮我优化一下这段文字的内容，并返回结果",
                text: "selected",
                model: "xinghuo"
              },
              {
                icon: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"></path><path d="M5 15V17C5 18.0544 5.81588 18.9182 6.85074 18.9945L7 19H10V21H7C4.79086 21 3 19.2091 3 17V15H5ZM18 10L22.4 21H20.245L19.044 18H14.954L13.755 21H11.601L16 10H18ZM17 12.8852L15.753 16H18.245L17 12.8852ZM8 2V4H12V11H8V14H6V11H2V4H6V2H8ZM17 3C19.2091 3 21 4.79086 21 7V9H19V7C19 5.89543 18.1046 5 17 5H14V3H17ZM6 6H4V9H6V6ZM10 6H8V9H10V6Z"></path></svg>`,
                name: "AI 英文翻译",
                prompt: "请帮我翻译下英语",
                text: "selected",
                model: "xinghuo"
              }
            ]
          }
        })
        await getTagsListApi()
        await getContentInfoApi(props.currId)
      })
    }
  }
)

const uploadCodeClickEvent = async (file: any) => {
  if ('image/png, image/jpeg, image/jpg'.indexOf(file.raw.type) === -1) {
    ElMessage({ type: 'error', message: '文件类型错误' })
    return false
  }
  if (file.raw.size > 1024 * 1024 * 5) {
    ElMessage({ type: 'error', message: '上传图片大小不能超过 5M' })
    return false
  }
  loading.value = true
  const formData = new FormData()
  formData.append('file', file.raw)
  formData.append('business', '内容图片组合')
  const res = await fileUpload(formData)
  loading.value = false
  if (res?.code === 200) {
    ElMessage({ type: 'success', message: '上传成功' });
    const data = res.data as OssApiResult[];
    const fileData = submotFileList.value as Array<any>;
    fileData.push({
      url: data[0].url,
      name: data[0].url,
      uid: file.uid as number
    })
  } else {
    ElMessage({ type: 'error', message: res?.msg || '网络异常，请稍后重试' })
  }
}

const dialogImageUrl = ref('')
const dialogVisible = ref(false)

const handlePictureCardPreview = (uploadFile: object) => {
  const file = uploadFile as uploadFile
  dialogImageUrl.value = file.url
  dialogVisible.value = true
}

const handlePictureCardDelete = (uploadFile: object) => {
  const file = uploadFile as uploadFile
  submotFileList.value = submotFileList.value.filter(item => item.uid !== file.uid);
}

const dataFormRef = ref()
const updateOrCreate = async () => {
  dataFormRef.value.validate(async (valid: boolean) => {
    if (valid) {
      const fileImg = submotFileList.value.map(item => {
        return item.name
      })
      dataForm.value.img = fileImg.join(',');
      dataForm.value.tags = tagsList.value
      dataForm.value.recom = recomList.value.join(',');
      dataForm.value.content = aiEditor.getHtml()
      loading.value = true
      const res = await updateContent(dataForm.value)
      loading.value = false
      if (res?.code === 200) {
        ElMessage({ type: 'success', message: '更新成功' })
        emit('change')
        handleClose()
      } else {
        ElMessage({ type: 'error', message: res?.msg || '网络异常，请稍后重试！' })
      }
    }
  })
}

const handleClose = () => {
  fileList.value = []
  submotFileList.value = []
  aiEditor.clear();
  aiEditor && aiEditor.destroy();
  emit(UPDATE_MODEL_EVENT, false)
}

// AI方法
const aiEvent = async (type: string, key: string, msg: string) => {
  loading.value = true
  let formKey = key;

  if (dataForm.value[formKey] === '') {
    ElMessage({ type: 'error', message: `请您输入${msg}` })
    loading.value = false
    return false;
  }

  const res = await aiSocket(type, dataForm.value[formKey]);

  if (res) {
    loading.value = false;
    const aiResultData = res as any
    dataForm.value[formKey] = `${aiResultData.data}`;
  }
}

// 素材库素材回填
const showOss = ref<boolean>(false)
const clickOssEvent = () => {
  showOss.value = true
}

const enterOss = (checkList: any) => {
  fileList.value = [...fileList.value, ...checkList]
  submotFileList.value = [...submotFileList.value, ...checkList]
}

// AI对话框列表
const aiList = ref<Array<any>>([]);
const aiContent = ref<string>('');
const aiBtnLoading = ref<boolean>(false)
const aiBtnList = ref([
  {
    label: '标题',
    value: '',
    keys: 'title'
  },
  {
    label: '简介',
    value: '',
    keys: 'intro'
  },
  {
    label: '关键词',
    value: '',
    keys: 'keyword'
  },
  {
    label: '描述',
    value: '',
    keys: 'description'
  }
]);

// 清空AI对话框
const clearDialog = () => {
  aiList.value = []
}

// 插入AI对应值
const insertionContent = (keys: string) => {
  const value = aiBtnList.value.find(item => item.keys === keys)?.value;
  dataForm.value[keys] = value;
}

// 发送AI内容
const submitAiDialog = async () => {
  aiBtnLoading.value = true;
  const res = await aiDialogSocket(aiContent.value);
  if (res) {
    loading.value = false;
    const aiResultData = res as any
    aiList.value.push({
      content: `${aiResultData.data}`
    });
    aiBtnList.value.forEach(item => {
      item.value = `${aiResultData.data}`
    })
    aiBtnLoading.value = false;
  }
  
}
</script>

<style scoped>
.img-uploader .img {
  width: 140px;
  height: 140px;
  display: block;
}
</style>

<style>
.img-uploader .el-upload {
  border: 1px dashed var(--el-border-color);
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: var(--el-transition-duration-fast);
}

.img-uploader .el-upload:hover {
  border-color: var(--el-color-primary);
}

.el-icon.img-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  text-align: center;
}
</style>